package org.coody.framework.core.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

@SuppressWarnings("unchecked")
public class ByteUtils {

	public static byte[] readLine(InputStream inputStream) throws IOException {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		while (true) {
			byte a = (byte) inputStream.read();
			if (a == '\n' || a == 0 || a == -1) {
				break;
			}
			outputStream.write(a);
		}

		return outputStream.toByteArray();
	}

	public static String readLineString(InputStream inputStream, String encode) {
		try {
			byte[] data = readLine(inputStream);
			if (CommonUtil.isNullOrEmpty(data)) {
				return null;
			}
			return new String(data, encode);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static byte[] read(InputStream inputStream) {
		ByteArrayOutputStream outputStream = null;
		try {
			outputStream = buildToOutputStream(inputStream);
			return outputStream.toByteArray();
		} catch (Exception e) {

			return null;
		} finally {
			try {
				outputStream.close();
			} catch (IOException e) {

			}
		}
	}

	public static byte[] read(InputStream inputStream, Integer length) {
		if (length < 1) {
			return null;
		}
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		try {
			while (length > 0) {
				byte[] chunked = new byte[length];
				int readed = inputStream.read(chunked);
				length = length - readed;
				outputStream.write(chunked, 0, readed);
			}
			byte[] bytes = outputStream.toByteArray();
			outputStream.close();
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static byte[] read(SocketChannel channel, Integer length) {
		if (length < 1) {
			return null;
		}
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		try {
			while (length > 0) {
				ByteBuffer buffer = ByteBuffer.allocate(length);
				int readed = channel.read(buffer);
				length = length - readed;
				byte[] data = new byte[buffer.remaining()];
				buffer.get(data);
				outputStream.write(data);
			}
			byte[] bytes = outputStream.toByteArray();
			outputStream.close();
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static <T extends OutputStream> T buildToOutputStream(InputStream inputStream) {
		OutputStream outputStream = new ByteArrayOutputStream();
		try {
			buildToOutputStream(inputStream, outputStream);
			return (T) outputStream;
		} catch (Exception e) {

			return null;
		}
	}

	public static <T extends OutputStream> T buildToOutputStream(InputStream inputStream, OutputStream outputStream) {
		if (outputStream == null) {
			outputStream = new ByteArrayOutputStream();
		}
		try {
			outputStream = new ByteArrayOutputStream();
			byte[] buff = new byte[1024];
			int rc = 0;
			while ((rc = inputStream.read(buff, 0, 1024)) > 0) {
				outputStream.write(buff, 0, rc);
			}
			return (T) outputStream;
		} catch (Exception e) {

			return null;
		}
	}
}
